<?php
/**
 * 用于生成excel文件操作
 *
 * @author Mo yi <root@imoi.cn>
 * @link   http://www.imoi.cn
 * @copyright Copyright &copy; 2010-2012 DuoLam Software LLC
 * @license http://www.imoi.cn/license/
 * @version $Id: dpExcel.php 1 2012-04-04 13:35:54Z Mo.yi $
 * @package web.helper
 * @since 1.0
 */

class dpExcel
{
    /**
     * EXCEL表格的xml代码
     *
     * @var string
     */
    protected $xmlTable;

    /**
     * EXCEL的标题xml代码
     *
     * @var string
     */
    protected $xmlMenu;

    /**
     * EXCEL的标题的个数
     *
     * @var integer
     */
    protected $colNum;

    /**
     * 处理EXCEL中一行代码,相当于HTML中的行标签<tr></tr>
     *
     * @param  array $data
     * @return string
     */
    protected function handleRow($data)
	{
        if (empty($data) || !is_array($data)) {
            return false;
        }

        $xml = "<Row>\n";

        foreach ($data as $key=>$value) {
            $xml .= ($key>0&&empty($data[$key-1])) ? $this->handleIndexCell($value, $key+1) : $this->handleCell($value);
        }

        $xml .= "</Row>\n";

        return $xml;
    }

    /**
     * 处理EXCEL多行数据的代码.
     *
     * @param array $data
     * @return string
     */
    protected function addRows($data)
	{
        if (empty($data) || !is_array($data) || !is_array($data[0])) {
            return false;
        }

        $xml_array = array();
        foreach ($data as $row) {
            $xml_array[] = $this->handleRow($row);
        }

        return implode('', $xml_array);
    }

    /**
     * 配置EXCEL表格的标题
     *
     * @param array $data 所要生成的excel的标题,注:参数为数组
     * @return boolean
     */
    public function setMenu($data)
	{
        if (empty($data) || !is_array($data) || is_array($data[0]) || array_search('', $data)) {
            return false;
        }

        $this->colNum = sizeof($data);
        $xml = "<Row ss:AutoFitHeight=\"0\" ss:Height=\"20\">\n";
        foreach ($data as $value) {
            $type = (is_numeric($data)&&(substr($data, 0, 1)!=0)) ? 'Number' : 'String';
            $xml .= "<Cell ss:StyleID=\"s22\"><Data ss:Type=\"" . $type . "\">" . $value . "</Data></Cell>\n";
        }
        $xml .= "</Row>\n";
        $this->xmlMenu = $xml;
        return true;
    }

    /**
     * 处理EXCEL表格的内容,相当于table.
     *
     * @param array $data
     * @return string
     */
    public function getData($data) 
	{
        $xml_rows = $this->addRows($data);
        if (empty($xml_rows)) {
            if (empty($this->xmlMenu))
                return false;
			else {
                $row_num = 1;
                $colNum = $this->colNum;
                $content = $this->xmlMenu;
            }
        } else {
            if (empty($this->xmlMenu)) {
                $row_num = sizeof($data);
                $colNum = sizeof($data[0]);
                $content = $xml_rows;
            } else {
                $row_num = sizeof($data)+1;
                $colNum = $this->colNum;
                $content = $this->xmlMenu.$xml_rows;
            }
        }
        return $this->xmlTable = "<Table ss:ExpandedColumnCount=\"" . $colNum . "\" ss:ExpandedRowCount=\"" . $row_num . "\" x:FullColumns=\"1\"x:FullRows=\"1\" ss:DefaultColumnWidth=\"60\"ss:DefaultRowHeight=\"20\">\n" . $content . "</Table>\n";
    }

    /**
     * 处理EXCEL表格信息代码
     *
     * @return string
     */
    protected function parseTable()
	{
        $xml_Worksheet = "<Worksheet ss:Name=\"Sheet1\">\n";
        if (empty($this->xmlTable)) {
            $xml_Worksheet .= "<Table ss:ExpandedColumnCount=\"0\" ss:ExpandedRowCount=\"0\" x:FullColumns=\"1\"
   x:FullRows=\"1\" ss:DefaultColumnWidth=\"60\" ss:DefaultRowHeight=\"20\"/>\n";
        } else {
			$xml_Worksheet .= $this->xmlTable;
		}
        $xml_Worksheet .= "<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\"><ProtectObjects>False</ProtectObjects><ProtectScenarios>False</ProtectScenarios></WorksheetOptions></Worksheet>\n";
        return $xml_Worksheet;
    }

    /**
     * 处理EXCEL中的表格,相当于html中的标签<td></td>
     *
     * @param string $data
     * @return string
     */
    protected function handleCell($data) 
	{
        if (empty($data) || is_array($data)) return false;
        $type = (is_numeric($data)&&(substr($data, 0, 1)!=0)) ? 'Number' : 'String';
        return "<Cell><Data ss:Type=\"".$type."\">" . $data . "</Data></Cell>\n";
    }

    /**
     * 处理EXCEL中CELL代码,当该CELL前的一个CELL内容为空时.
     *
     * @param string $data
     * @param integer $key
     * @return string
     */
    protected function handleIndexCell($data, $key)
	{
        if (empty($data) || is_array($data))  return false;
        $type = (is_numeric($data)&&(substr($data, 0, 1)!=0)) ? 'Number' : 'String';
        return "<Cell ss:Index=\"" . $key . "\"><Data ss:Type=\"" . $type . "\">" . $data . "</Data></Cell>\n";
    }


    /**
     * 分析EXCEL的文件头
     *
     * @return tring
     */
    protected function parseHeader()
	{
        return "<?xml version=\"1.0\"?>
<?mso-application progid=\"Excel.Sheet\"?>
<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"
 xmlns:o=\"urn:schemas-microsoft-com:office:office\"
 xmlns:x=\"urn:schemas-microsoft-com:office:excel\"
 xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"
 xmlns:html=\"http://www.w3.org/TR/REC-html40\">\n";
    }

    /**
     * 分析EXCEL的内容格式
     *
     * @return string
     */
    protected function parseTop()
	{
        return "<ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\">
  <WindowHeight>13500</WindowHeight>
  <WindowWidth>20340</WindowWidth>
  <WindowTopX>360</WindowTopX>
  <WindowTopY>75</WindowTopY>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
 </ExcelWorkbook>
 <Styles>
  <Style ss:ID=\"Default\" ss:Name=\"Normal\">
   <Alignment ss:Vertical=\"Center\"/>
   <Borders/>
   <Font ss:FontName=\"宋体\" x:CharSet=\"134\" ss:Size=\"12\"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
  <Style ss:ID=\"s22\">
   <Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\"/>
  </Style>
 </Styles>\n";
    }

    /**
     * 分析EXCEL的结尾
     *
     * @return string
     */
    protected function parseFooter()
	{
        return "<Worksheet ss:Name=\"Sheet2\">
  <Table ss:ExpandedColumnCount=\"0\" ss:ExpandedRowCount=\"0\" x:FullColumns=\"1\"
   x:FullRows=\"1\" ss:DefaultColumnWidth=\"60\" ss:DefaultRowHeight=\"20\"/>
  <WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>
 <Worksheet ss:Name=\"Sheet3\">
  <Table ss:ExpandedColumnCount=\"0\" ss:ExpandedRowCount=\"0\" x:FullColumns=\"1\"
   x:FullRows=\"1\" ss:DefaultColumnWidth=\"60\" ss:DefaultRowHeight=\"20\"/>
  <WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>
 </Workbook>";
    }

    /**
     * 生成EXCEL文件并下载.
     *
     * @param string $file_name    所要生成的excel的文件名,注:文件名中不含后缀名
     */
    public function download($file_name)
	{
        if (empty($file_name)) return false;

        header('Pragma: no-cache');
        header("Content-Type: application/vnd.ms-excel; name=\"".$file_name.".xls\"");
        header("Content-Disposition: inline; filename=\"" . $file_name . ".xls\"");
        $excel_xml = $this->parseHeader().$this->parseTop().$this->parseTable().$this->parseFooter();

        echo $excel_xml;
    }
}